#pragma once
#include <iostream>
#include <cstring>
#include <cassert>
namespace wxd
{
    template <class T>
    class vector
    {
    public:
        typedef T *iterator;
        typedef const T *const_iterator;

        iterator begin()
        {
            return _start;
        }

        iterator end()
        {
            return _finish;
        }
        const_iterator begin() const
        {
            return _start;
        }
        const_iterator end() const
        {
            return _finish;
        }

        // 构造函数-默认构造
        vector() : _start(nullptr), _finish(nullptr), _end_of_storage(nullptr)
        {
        }
        // 构造函数-n个相同构造
        vector(int n, const T &val = T()) : _start(nullptr), _finish(nullptr), _end_of_storage(nullptr)
        {
            while (n--)
            {
                push_back(val);
            }
        }
        //迭代器区间构造
        template<class InputIterator>
        vector(InputIterator first,InputIterator last)
        {
            while(first != last)
            {
                //std::cout<<"first:"<<*first<<std::endl;
                push_back(*first);
                ++first;
            }
        }

        // //拷贝构造
        // vector(const vector& v)
        // {
        //     _start = new T[v.capacity()];
        //     memcpy(_start,v._start,sizeof(T)*v.size());
        //     _finish = _start + v.size();
        //     _end_of_storage = _start + v.capacity();
        // }


        //拷贝构造
        vector(const vector& v)
        {
            reserve(v.capacity());
            for(auto& x:v)
            {
                push_back(x);
            }
        }
        void swap(vector& v)
        {
            std::swap(_start,v._start);
            std::swap(_end_of_storage,v._end_of_storage);
            std::swap(_finish,v._finish);
        }
        vector& operator=(vector v)
        {
            this->swap(v);
            return *this;
        }

        T &operator[](size_t pos)
        {
            assert(pos >= 0 && pos < size());
            return _start[pos];
        }
        T operator[](size_t pos) const
        {
            assert(pos >= 0 && pos < size());
            return _start[pos];
        }
        size_t size() const;
        size_t capacity() const;
        void push_back(const T &val = T());
        void reserve(size_t n);
        bool empty() const;
        void pop_back();
        void resize(size_t n, const T &val = T());
        iterator insert(iterator pos, const T &val = T());
        iterator erase(iterator pos);

        ~vector()
        {
            delete[] _start;
            _start = _finish = _end_of_storage;
        }

    private:
        // 三个指针维护vector
        T *_start = nullptr;
        T *_finish = nullptr;
        T *_end_of_storage = nullptr;
    };

    template <class T>
    size_t vector<T>::size() const
    {
        return _finish - _start;
    }
    template <class T>
    size_t vector<T>::capacity() const
    {
        return _end_of_storage - _start;
    }
    template <class T>
    void vector<T>::push_back(const T &val)
    {
        // 扩容
        if (size() == capacity())
        {
            size_t new_capacity = size() == 0 ? 4 : 2 * capacity();
            reserve(new_capacity);
        }
        // 插入
        //_start[size()] = val;
        *_finish = val;
        _finish++;
    }

    template <class T>
    void vector<T>::reserve(size_t n) // 扩容不缩容
    {
        if (n > capacity())
        {
            // size的计算是依赖_start和_finish的，所以要保存一下
            size_t old_size = size();
            // 扩容
            T *tmp = new T[n];
            // // 拷贝 - 如果这里面的指针指向的是一个动态开辟内存的类，会出现浅拷贝的现象
            // memcpy(tmp, _start, old_size * sizeof(T));
            for(size_t i = 0;i < old_size;i++)
            {
                tmp[i] = _start[i];//调用类类型对象的operator=，实现深拷贝
            }
            // 释放
            delete[] _start;
            // 调整指针
            _start = tmp;
            _finish = _start + old_size;
            _end_of_storage = _start + n;

            // debug
            std::cout << "reserve success!" << std::endl;
        }
    }
    template <class T>
    bool vector<T>::empty() const
    {
        return !(_finish - _start);
    }

    template <class T>
    void vector<T>::pop_back()
    {
        // 断言不能删空
        assert(!empty());
        _finish--;
    }

    template <class T>
    typename vector<T>::iterator vector<T>::insert(iterator pos, const T &val)
    {
        // 断言pos
        assert(pos >= begin() && pos <= end());
        // 记录迭代器的相对位置
        size_t gap = pos - _start;
        // 扩容
        if (size() == capacity())
        {
            size_t new_capacity = size() == 0 ? 4 : 2 * capacity();
            reserve(new_capacity);
        }
        // 恢复迭代器的位置
        pos = _start + gap;
        // 移动
        for (iterator end = _finish - 1; end >= pos; end--)
        {
            *(end + 1) = *end;
        }
        // 插入
        *pos = val;
        _finish++;

        return pos;
    }

    template <class T>
    typename vector<T>::iterator vector<T>::erase(iterator pos)
    {
        // 断言
        assert(pos >= begin() && pos < end());
        // 覆盖式删除
        iterator cur = pos;
        while (cur != end())
        {
            *cur = *(cur + 1);
            cur++;
        }

        _finish--;
        return pos;
    }

    template <class T>
    void vector<T>::resize(size_t n, const T &val)
    {
        if (n <= size())
        {
            _finish = _start + n;
        }
        else
        {
            size_t cnt = n - size();
            while(cnt--)
            {
                push_back(val);
            }
        }
    }
};
